package com.cp.weixin.util;

import com.cp.weixin.es.repository.Phrase;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.*;

@Component
public class ElasticsearchUtil {
    private static final Logger LOGGER = LogManager.getLogger();

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    private static RestHighLevelClient client;

    @PostConstruct
    public void init() {
        client = this.restHighLevelClient;
    }

    /**
     * 删除索引
     * @param index
     * @return
     */
    public static boolean deleteIndex(String index) {
        DeleteIndexRequest request = new DeleteIndexRequest(index);
        try {
            DeleteIndexResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
            return response.isAcknowledged();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 单条导入索引
     * @param phrase
     * @return
     */
    public static IndexResponse addData(Phrase phrase) {
        IndexRequest request = formatIndexRequest(phrase);
        try {
            IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
            return indexResponse;
        } catch(Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    private static IndexRequest formatIndexRequest(Phrase phrase) {
        String uuid = phrase.getUuid();
        IndexRequest request = new IndexRequest("chengyu", "item", uuid);
        Map<String, Object> map = new HashMap<>();
        map.put("id", phrase.getUuid());
        map.put("entry", phrase.getEntry());
        map.put("pinyin", phrase.getPinyin());
        map.put("content", phrase.getContent());
        request.source(map);
        return request;
    }

    /**
     * 批量导入索引
     * @param list
     * @return
     */
    public static BulkResponse bulkAddData(List<Phrase> list) {
        String uuid = "";
        BulkRequest request = new BulkRequest();
        for(Phrase phrase : list) {
            request.add(formatIndexRequest(phrase));
        }
        try {
            return client.bulk(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    private static SearchRequest getRequest(String text, int from, int size) {
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchRequest.indices("chengyu");
//        searchSourceBuilder.query(QueryBuilders.multiMatchQuery(text, "title", "content"));
        searchSourceBuilder.query(QueryBuilders.queryStringQuery(text));
        searchSourceBuilder.from(from);
        searchSourceBuilder.size(size);


        HighlightBuilder highlightBuilder = new HighlightBuilder();
//        HighlightBuilder.Field highlightEntry = new HighlightBuilder.Field("entry");
//        highlightEntry.highlighterType("unified");
//        highlightBuilder.field(highlightEntry);
        HighlightBuilder.Field highlightContent = new HighlightBuilder.Field("content");
        highlightContent.highlighterType("unified");
        highlightBuilder.field(highlightContent);
        searchSourceBuilder.highlighter(highlightBuilder);

        searchRequest.source(searchSourceBuilder);
        return searchRequest;
    }

    public static SearchResponse search(String text, int from, int size) {
        SearchRequest request = getRequest(text, from, size);
        try {
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            return response;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


//
//    /**
//     * 创建索引
//     *
//     * @param index
//     * @return
//     */
//    public static boolean createIndex(String index) {
//        if (!isIndexExist(index)) {
//            LOGGER.info("Index is not exits!");
//        }
//        CreateIndexResponse indexresponse = client.admin().indices().prepareCreate(index).execute().actionGet();
//        LOGGER.info("执行建立成功？" + indexresponse.isAcknowledged());
//        return indexresponse.isAcknowledged();
//    }
//
//    /**
//     * 删除索引
//     *
//     * @param index
//     * @return
//     */
//    public static boolean deleteIndex(String index) {
//        if (!isIndexExist(index)) {
//            LOGGER.info("Index is not exits!");
//        }
//        DeleteIndexResponse dResponse = client.admin().indices().prepareDelete(index).execute().actionGet();
//        if (dResponse.isAcknowledged()) {
//            LOGGER.info("delete index " + index + "  successfully!");
//        } else {
//            LOGGER.info("Fail to delete index " + index);
//        }
//        return dResponse.isAcknowledged();
//    }
//
//    /**
//     * 判断索引是否存在
//     *
//     * @param index
//     * @return
//     */
//    public static boolean isIndexExist(String index) {
//        IndicesExistsResponse inExistsResponse = client.admin().indices().exists(new IndicesExistsRequest(index)).actionGet();
//        if (inExistsResponse.isExists()) {
//            LOGGER.info("Index [" + index + "] is exist!");
//        } else {
//            LOGGER.info("Index [" + index + "] is not exist!");
//        }
//        return inExistsResponse.isExists();
//    }
//
//    /**
//     * @Description: 判断inde下指定type是否存在
//     */
//    public boolean isTypeExist(String index, String type) {
//        return isIndexExist(index)
//                ? client.admin().indices().prepareTypesExists(index).setTypes(type).execute().actionGet().isExists()
//                : false;
//    }
//
//    /**
//     * 数据添加，自定ID
//     *
//     * @param jsonObject 要增加的数据
//     * @param index      索引，类似数据库
//     * @param type       类型，类似表
//     * @param id         数据ID
//     * @return
//     */
//    public static String addData(JSONObject jsonObject, String index, String type, String id) {
//        IndexResponse response = client.prepareIndex(index, type, id).setSource(jsonObject).get();
//        LOGGER.info("addData response status:{},id:{}", response.status().getStatus(), response.getId());
//        return response.getId();
//    }
//
//    /**
//     * 数据添加
//     *
//     * @param jsonObject 要增加的数据
//     * @param index      索引，类似数据库
//     * @param type       类型，类似表
//     * @return
//     */
//    public static String addData(JSONObject jsonObject, String index, String type) {
//        return addData(jsonObject, index, type, UUID.randomUUID().toString());
//    }
//
//    /**
//     * 通过ID删除数据
//     *
//     * @param index 索引，类似数据库
//     * @param type  类型，类似表
//     * @param id    数据ID
//     */
//    public static void deleteDataById(String index, String type, String id) {
//
//        DeleteResponse response = client.prepareDelete(index, type, id).execute().actionGet();
//
//        LOGGER.info("deleteDataById response status:{},id:{}", response.status().getStatus(), response.getId());
//    }
//
//    /**
//     * 通过ID 更新数据
//     *
//     * @param jsonObject 要增加的数据
//     * @param index      索引，类似数据库
//     * @param type       类型，类似表
//     * @param id         数据ID
//     * @return
//     */
//    public static void updateDataById(JSONObject jsonObject, String index, String type, String id) {
//
//        UpdateRequest updateRequest = new UpdateRequest();
//
//        updateRequest.index(index).type(type).id(id).doc(jsonObject);
//
//        client.update(updateRequest);
//
//    }
//
//    /**
//     * 通过ID获取数据
//     *
//     * @param index  索引，类似数据库
//     * @param type   类型，类似表
//     * @param id     数据ID
//     * @param fields 需要显示的字段，逗号分隔（缺省为全部字段）
//     * @return
//     */
//    public static Map<String, Object> searchDataById(String index, String type, String id, String fields) {
//
//        GetRequestBuilder getRequestBuilder = client.prepareGet(index, type, id);
//
//        if (StringUtils.isNotEmpty(fields)) {
//            getRequestBuilder.setFetchSource(fields.split(","), null);
//        }
//
//        GetResponse getResponse = getRequestBuilder.execute().actionGet();
//
//        return getResponse.getSource();
//    }
//
//
//    /**
//     * 使用分词查询,并分页
//     *
//     * @param index          索引名称
//     * @param type           类型名称,可传入多个type逗号分隔
//     * @param startPage      当前页
//     * @param pageSize       每页显示条数
//     * @param query          查询条件
//     * @param fields         需要显示的字段，逗号分隔（缺省为全部字段）
//     * @param sortField      排序字段
//     * @param highlightField 高亮字段
//     * @return
//     */
//    public static EsPage searchDataPage(String index, String type, int startPage, int pageSize, QueryBuilder query, String fields, String sortField, String highlightField) {
//        SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
//        if (StringUtils.isNotEmpty(type)) {
//            searchRequestBuilder.setTypes(type.split(","));
//        }
//        searchRequestBuilder.setSearchType(SearchType.QUERY_THEN_FETCH);
//
//        // 需要显示的字段，逗号分隔（缺省为全部字段）
//        if (StringUtils.isNotEmpty(fields)) {
//            searchRequestBuilder.setFetchSource(fields.split(","), null);
//        }
//
////排序字段
//        if (StringUtils.isNotEmpty(sortField)) {
//            searchRequestBuilder.addSort(sortField, SortOrder.DESC);
//        }
//
//// 高亮（xxx=111,aaa=222）
//        if (StringUtils.isNotEmpty(highlightField)) {
//            HighlightBuilder highlightBuilder = new HighlightBuilder();
//
//            //highlightBuilder.preTags("<span style='color:red' >");//设置前缀
//            //highlightBuilder.postTags("</span>");//设置后缀
//
//            // 设置高亮字段
//            highlightBuilder.field(highlightField);
//            searchRequestBuilder.highlighter(highlightBuilder);
//
//
//        }
//
////searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery());
//        searchRequestBuilder.setQuery(query);
//
//        // 分页应用
//        searchRequestBuilder.setFrom(startPage).setSize(pageSize);
//
//        // 设置是否按查询匹配度排序
//        searchRequestBuilder.setExplain(true);
//
//        //打印的内容 可以在 Elasticsearch head 和 Kibana  上执行查询
//        LOGGER.info("\n{}", searchRequestBuilder);
//
//        // 执行搜索,返回搜索响应信息
//        SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
//
//        long totalHits = searchResponse.getHits().totalHits;
//        long length = searchResponse.getHits().getHits().length;
//
//        LOGGER.debug("共查询到[{}]条数据,处理数据条数[{}]", totalHits, length);
//
//        if (searchResponse.status().getStatus() == 200) {
//// 解析对象
//            List<Map<String, Object>> sourceList = setSearchResponse(searchResponse, highlightField);
//
//            return new EsPage(startPage, pageSize, (int) totalHits, sourceList);
//        }
//
//        return null;
//
//    }
//
//
//    /**
//     * 使用分词查询
//     *
//     * @param index          索引名称
//     * @param type           类型名称,可传入多个type逗号分隔
//     * @param query          查询条件
//     * @param size           文档大小限制
//     * @param fields         需要显示的字段，逗号分隔（缺省为全部字段）
//     * @param sortField      排序字段
//     * @param highlightField 高亮字段
//     * @return
//     */
//    public static List<Map<String, Object>> searchListData(
//            String index, String type, QueryBuilder query, Integer size,
//            String fields, String sortField, String highlightField) {
//
//        SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
//        if (StringUtils.isNotEmpty(type)) {
//            searchRequestBuilder.setTypes(type.split(","));
//        }
//
//        if (StringUtils.isNotEmpty(highlightField)) {
//            HighlightBuilder highlightBuilder = new HighlightBuilder();
//            // 设置高亮字段
//            highlightBuilder.field(highlightField);
//            searchRequestBuilder.highlighter(highlightBuilder);
//        }
//
//        searchRequestBuilder.setQuery(query);
//
//        if (StringUtils.isNotEmpty(fields)) {
//            searchRequestBuilder.setFetchSource(fields.split(","), null);
//        }
//        searchRequestBuilder.setFetchSource(true);
//
//        if (StringUtils.isNotEmpty(sortField)) {
//            searchRequestBuilder.addSort(sortField, SortOrder.DESC);
//        }
//
//        if (size != null && size > 0) {
//            searchRequestBuilder.setSize(size);
//        }
//
//        //打印的内容 可以在 Elasticsearch head 和 Kibana  上执行查询
//        LOGGER.info("\n{}", searchRequestBuilder);
//
//        SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
//
//        long totalHits = searchResponse.getHits().totalHits;
//        long length = searchResponse.getHits().getHits().length;
//
//        LOGGER.info("共查询到[{}]条数据,处理数据条数[{}]", totalHits, length);
//
//        if (searchResponse.status().getStatus() == 200) {
//            // 解析对象
//            return setSearchResponse(searchResponse, highlightField);
//        }
//        return null;
//
//    }
//
//
//    /**
//     * 高亮结果集 特殊处理
//     *
//     * @param searchResponse
//     * @param highlightField
//     */
//    private static List<Map<String, Object>> setSearchResponse(SearchResponse searchResponse, String highlightField) {
//        List<Map<String, Object>> sourceList = new ArrayList<Map<String, Object>>();
//        StringBuffer stringBuffer = new StringBuffer();
//
//        for (SearchHit searchHit : searchResponse.getHits().getHits()) {
//            searchHit.getSourceAsMap().put("id", searchHit.getId());
//
//            if (StringUtils.isNotEmpty(highlightField)) {
//
//                System.out.println("遍历 高亮结果集，覆盖 正常结果集" + searchHit.getSourceAsMap());
//                Text[] text = searchHit.getHighlightFields().get(highlightField).getFragments();
//
//                if (text != null) {
//                    for (Text str : text) {
//                        stringBuffer.append(str.string());
//                    }
////遍历 高亮结果集，覆盖 正常结果集
//                    searchHit.getSourceAsMap().put(highlightField, stringBuffer.toString());
//                }
//            }
//            sourceList.add(searchHit.getSourceAsMap());
//        }
//
//        return sourceList;
//    }
}
